
package com.hzt.agprosaleplatform.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.hzt.agprosaleplatform.mapper.AddressMapper;
import com.hzt.agprosaleplatform.mapper.OrderMapper;
import com.hzt.agprosaleplatform.mapper.ShopMapper;
import com.hzt.agprosaleplatform.entity.Address;
import com.hzt.agprosaleplatform.entity.Order;
import com.hzt.agprosaleplatform.entity.Shop;
import com.hzt.agprosaleplatform.dto.RouteDTO;
import com.hzt.agprosaleplatform.dto.RoutePointDTO;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.HashMap;

@Service
public class LogisticsService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private ShopMapper shopMapper;

    private final RestTemplate restTemplate = new RestTemplate();

    // 从 application.yml 或其他配置中注入您的高德Key
    @Value("${amap.key}")
    private String amapKey;

    private static final String AMAP_GEOCODE_URL = "https://restapi.amap.com/v3/geocode/geo?key={key}&address={address}&city={city}";

    public RouteDTO getRouteForOrder(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("Order not found with ID: " + orderId);
        }

        Address destinationAddress = addressMapper.selectById(order.getAddress_id());
        Shop originShop = shopMapper.selectById(order.getShop_id());

        if (destinationAddress == null) {
            throw new IllegalArgumentException("Destination address not found for address_id: " + order.getAddress_id());
        }
        if (originShop == null) {
            throw new IllegalArgumentException("Origin shop not found for shop_id: " + order.getShop_id());
        }

        // 检查详细地址是否存在
        if (originShop.getAddress() == null || originShop.getAddress().isBlank()) {
            throw new IllegalArgumentException("Origin shop address details are missing for shop_id: " + originShop.getShopId());
        }
        if (destinationAddress.getAddress() == null || destinationAddress.getAddress().isBlank()) {
            throw new IllegalArgumentException("Destination address details are missing for address_id: " + destinationAddress.getAid());
        }

        RoutePointDTO startPoint = geocodeAddress(originShop.getCity(), originShop.getAddress());
        RoutePointDTO endPoint = geocodeAddress(destinationAddress.getCity(), destinationAddress.getAddress());

        return new RouteDTO(startPoint, endPoint);
    }

    private RoutePointDTO geocodeAddress(String city, String address) {
        Map<String, String> uriVariables = new HashMap<>();
        uriVariables.put("key", amapKey);
        uriVariables.put("address", address);
        uriVariables.put("city", city);

        LoggerFactory.getLogger(LogisticsService.class).info("Requesting AMap Geocoding with city: {} and address: {}", city, address);

        // 让 RestTemplate 自动处理编码
        String response = restTemplate.getForObject(AMAP_GEOCODE_URL, String.class, uriVariables);

        JSONObject jsonResponse = JSON.parseObject(response);
        if (!"1".equals(jsonResponse.getString("status"))) {
            throw new RuntimeException("Geocoding API error: " + jsonResponse.getString("info"));
        }

        JSONArray geocodes = jsonResponse.getJSONArray("geocodes");
        if (geocodes == null || geocodes.isEmpty()) {
            throw new RuntimeException("Address not found by geocoding API: " + address);
        }

        String location = geocodes.getJSONObject(0).getString("location");
        String[] lonLat = location.split(",");
        
        double lon = Double.parseDouble(lonLat[0]);
        double lat = Double.parseDouble(lonLat[1]);

        return new RoutePointDTO(lon, lat);
    }
}
